package com.gjy.encoder;

import com.gjy.encoder.security.GMCertificate;
import com.gjy.encoder.utils.SM2Utils;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * @author gjy
 * @version 1.0
 * @since 2025-07-25 11:07:09
 */
public class Sm2Utils {

    public static void main(String[] args) {
        System.out.println("---------------------加签测试--开始------------------------------");
        //秘钥信息
        String priKey = "VinxdPzSzQ5otkeCPzOPHd+MJlvZMdpJo9r/qR7S/Oc=";
        String pubKey = "BMgzOnZWea663W/Ef2DvuRvNI7zUtpFNCTlkGu1dYMSlwEiaw5cZK0lrRyMwciRJvlYty3gzXB9+tlHByEkyl3Y=";
        String msg = pubKey + "@{\"PRI_KEY\":\"20240401112530910DLk\",\"SOURCE\":\"NX-***\",\"STATEMENT_NAME\":\"中国****集团**分公司结算单20240401000001\",\"PAY_NUM\":\"**20240401000001101814808896\",\"BANK_ACCOUNT_NAME\":\"石景山\",\"BANK_ACCOUNT_NUM\":\"**8801490000****\",\"OPBANK_ACCOUNT_NAME\":\"陈*\",\"OPBANK_ACCOUNT_NUM\":\"6225885123771****\",\"OPBANK_TAPE\":\"银行卡\",\"OP_CNAPS_NAME\":\"中国工商银行股份有限公司北京**支行\",\"OP_CNAPS_NUM\":\"1021000000**\",\"AMOUNT\":10.0,\"SUMMARY\":\"司库划扣\",\"PAY_CURRENCY_CODE\":\"CNY\",\"BOUNCED\":\"0\",\"SDATE\":\"20240401\",\"BUSINESS_TYPE\":\"02\"}";
        //加签方法1（推荐使用）
        String sign1 = SM2Utils.sign(priKey, msg);
        System.out.println("1-本次生成的签名1：" + sign1);
        //加签方法2
        String sign2 = SM2Utils.sign(SM2Utils.decode(priKey), SM2Utils.getBytes(msg));
        System.out.println("2-本次生成的签名2：" + sign2);
        //验签方法1（推荐使用）
        boolean ret1 = SM2Utils.verify(pubKey, msg, sign1);
        System.out.println("3-验签-本次方法1加签校验结果：" + ret1);
        //验签方法2
        boolean ret2 = SM2Utils.verify(SM2Utils.decode(pubKey), SM2Utils.getBytes(msg), SM2Utils.decode(sign2));
        System.out.println("4-验签-本次加签校验结果：" + ret2);
        //某次使用秘钥加签的签名
        String sign3 = "MEQCICytsk+6dWbNOaZxH6aokActwyVi/USGYHCtjIYrGpA+AiARJxrtbGa1fPpj1j2MXwD8J6cM7ROjfI9Pb/kKE+pC/g==";
        boolean ret3 = SM2Utils.verify(SM2Utils.decode(pubKey), SM2Utils.getBytes(msg), SM2Utils.decode(sign3));
        System.out.println("5-验签-验证某次加签结果：" + ret3);
        String sign4 = "AEQCICytsk+6dWbNOaZxH6aokActwyVi/USGYHCtjIYrGpA+AiARJxrtbGa1fPpj1j2MXwD8J6cM7ROjfI9Pb/kKE+pC/g==";
        boolean ret4 = SM2Utils.verify(SM2Utils.decode(pubKey), SM2Utils.getBytes(msg), SM2Utils.decode(sign4));
        System.out.println("6-验签-验证失败结果：" + ret4);
        System.out.println("---------------------加签测试--结束------------------------------");
        System.out.println("---------------------加密测试--开始------------------------------");
        System.out.println("注意：");
        System.out.println("    1、SM2加密解密功能共用加签验签使用的秘钥对信息：");
        System.out.println("        使用公钥加密，使用私钥解密，每次使用加密的字符串内容不同，长度相同，但都能使用正确的私钥解密；");
        System.out.println("    2、加密后字符长度和源数据之间的计算公式为：");
        System.out.println("        加密后字段长度=132 + （向下取整（加密字符串字节长度/3））*4");
        System.out.println("        其中汉字及标点（UTF-8）占3个字节，英文、阿拉伯数字、英文标点等占1个字节；");
        System.out.println("    3、空字符串无需加密，空字符串或者异常加密信息在使用SM2Utils.encrypt解密时返回空字符串，可用来判断是否可以解密成功。");
        GMCertificate gmCertificate = new GMCertificate(SM2Utils.decode(pubKey), SM2Utils.decode(priKey));
        String testMsg = "落霞与孤鹜齐飞，秋水共长天一色。";
        //加密方法1（推荐使用）
        String encyptMsg1 = SM2Utils.encrypt(testMsg, pubKey);
        System.out.println("1-加密后数据(方法1）：" + encyptMsg1);
        System.out.println("2-解密数据(方法1）：" + SM2Utils.decrypt(encyptMsg1, priKey));
        //加密方法2
        String encyptMsg2 = "";
        if (testMsg != null && !testMsg.isEmpty()) {
            encyptMsg2 = Base64.getEncoder().encodeToString(gmCertificate.encrypt(testMsg.getBytes(StandardCharsets.UTF_8)));
        }
        System.out.println("3-加密后数据(方法2）：" + encyptMsg2);
        String decryptMsg2 = "";
        if (encyptMsg2 != null && !encyptMsg2.isEmpty()) {
            decryptMsg2 = new String(gmCertificate.decrypt(SM2Utils.decode(encyptMsg2)));
        }
        System.out.println("4-解密数据(方法2）：" + decryptMsg2);
        String encryptMsg3 = "BHQzVrnfatwzSVp6EKpt2132u1v7VpRcfvrrp8lZPBadnt7EhB9ZydKmBbxlfrU0RgezJF5QRmBwCBfsZU+YyUK13zvv/eaGSbnaBAvN04aroismT1BcTrsELDPSFCJ2CD1zwmbpsJmVUqjWwKUHdd8AnF3f22GEUHbgsP1SlmWx0r6SJ5qWkbfXKrRG88YOOw==";
        System.out.println("5-解密错误时返回空字符串：" + SM2Utils.decrypt(encryptMsg3, priKey));
        System.out.println("---------------------加签测试--结束------------------------------");
    }
}
